﻿#include "include/non_standard_utility.h"

/**
 * @brief Non_Standard_Utility::ascii2Num ascii转16进制,注意:当输入并非16进制数字,则返回-1
 * @param input
 * @return
 */
int Non_Standard_Utility::ascii2Hex( char input ) {
    if ( ( input >= 0x30 ) && ( input <= 0x39 ) ) { input -= 0x30; }
    else if ( ( input >= 0x41 ) && ( input <= 0x46 ) ) {
        input -= 0x37;
    }
    else if ( ( input >= 0x61 ) && ( input <= 0x66 ) ) {
        input -= 0x57;
    }
    else {
        input = -1;
    }
    return input;
}

/**
 * @brief Non_Standard_Utility::delayMs 非阻塞式延时函数
 * @param mSec 延迟的毫秒数
 */
void Non_Standard_Utility::delayMs( const int& mSec ) {
    QEventLoop* loop = new QEventLoop();

    QTimer::singleShot( mSec, loop, SLOT( quit() ) );
    loop->exec();
}

void Non_Standard_Utility::blockDelayMs( int ms ) {
    QElapsedTimer dieTime;

    dieTime.start();
    while ( dieTime.elapsed() < ms ) {
    }
}

/**
 * @brief Non_Standard_Utility::BCC 异或校验，对传入的字节数组进行异或，得出校验值
 * @param order 传入的字节数组
 * @param len 需要校验的长度
 * @return 校验值
 */
char Non_Standard_Utility::BCC( const QByteArray& order, int len ) {
    char bcc = 0x00;

    for ( int i = 0; i <= len; i++ ) {
        bcc ^= order.at( i );
    }
    return bcc;
}

/**
 * @brief Non_Standard_Utility::BCC 异或校验，对传入的字节数组进行异或，得出校验值
 * @param order 传入的字节数组
 * @param start 起始的index
 * @param len 需要校验的长度
 * @return 校验值
 */
char Non_Standard_Utility::BCC( const QByteArray& order, int start, int len ) {
    char bcc = 0x00;

    for ( int i = start; i < start + len; i++ ) {
        bcc ^= order.at( i );
    }
    return bcc;
}

/**
 * @brief Non_Standard_Utility::CKS 和校验，对传入的字节数组进行相加，溢出部分去掉，只保留最低位字节
 * @param order 传入的字节数组
 * @param len 校验的长度
 * @return 校验值
 */
uchar Non_Standard_Utility::CKS( const QByteArray& order, int len ) {
    uchar result = 0x00;

    for ( int i = 0; i < len; i++ ) {
        result += order.at( i );
    }
    return result;
}

/**
 * @brief Non_Standard_Utility::CKS4TL740D 和校验，对传入的字节数组进行相加，溢出部分去掉，只保留最低位字节
 * @param order 传入的字节数组
 * @param start 开始的index
 * @param len 校验的长度
 * @return 校验值
 */
uchar Non_Standard_Utility::CKS( const QByteArray& order, int start, int len ) {
    uchar crc = 0;

    for ( int i = start; i < start + len; i++ ) {
        crc += order.at( i );
    }
    return crc;
}

/**
 * @brief Non_Standard_Utility::CRC16_ModBus CRC16位校验
 * @param order 传入的字节数组
 * @param num 开始的index
 * @return 校验值
 */
QByteArray Non_Standard_Utility::CRC16_ModBus( const QByteArray& order, int num ) {
    quint16    crcRegistor = 0xFFFF;
    int        index       = num;
    QByteArray crc( 2, 0x00 );

    while ( num-- ) {
        crcRegistor ^= ( uchar( order.at( index - num - 1 ) ) );
        //      printf("%x ", (uchar)order.at(index - num - 1));
        //      crcRegistor ^= (order.at(index-num-1) & 0xFF);
        for ( qint8 i = 0; i < 8; i++ ) {
            if ( crcRegistor & 1 ) {
                crcRegistor = ( crcRegistor >> 1 ) ^ 0xA001;  //串口数据传输时低位在前，高位在后，8005应该倒过来读，就是A001
            }
            else {
                crcRegistor >>= 1;
            }
        }
    }
    //   qDebug() << QString::number(crcRegistor, 16);
    crc[ 0 ] = static_cast< char >( crcRegistor );
    crc[ 1 ] = static_cast< char >( crcRegistor >> 8 );
    return crc;
}

QByteArray Non_Standard_Utility::CRC16_X25( const QByteArray& order, int num ) {
    quint16    crcRegistor = 0xFFFF;
    int        index       = num;
    QByteArray crc( 2, 0x00 );

    while ( num-- ) {
        crcRegistor ^= ( uchar( order.at( index - num - 1 ) ) );
        //           printf("%x ",(uchar)order.at(index-num-1));
        //        crcRegistor ^= (order.at(index-num-1) & 0xFF);
        for ( qint8 i = 0; i < 8; i++ ) {
            if ( crcRegistor & 1 ) {
                crcRegistor = ( crcRegistor >> 1 ) ^ 0x8408;  //串口数据传输时低位在前，高位在后，8005应该倒过来读，就是A001
            }
            else {
                crcRegistor >>= 1;
            }
        }
    }

    crcRegistor ^= 0xFFFF;
    //       qDebug()<<QString::number(crcRegistor,16);
    crc[ 0 ] = static_cast< char >( crcRegistor );
    crc[ 1 ] = static_cast< char >( crcRegistor >> 8 );
    return crc;
}

QString Non_Standard_Utility::QbyteArry2Qstring( const QByteArray& data ) {
    QString strDisplay;
    QString str = data.toHex().data();

    str = str.toUpper();
    for ( int i = 0; i < str.length(); i += 2 ) {
        QString st = str.mid( i, 2 );
        strDisplay += st;
        strDisplay += " ";
    }
    return strDisplay;
}
Non_Standard_Utility::Non_Standard_Utility() = default;
